const axios = require('axios');
const wechatConfig = require('../config/wechat');

class WechatService {
  constructor() {
    this.config = wechatConfig.openPlatform;
    this.api = wechatConfig.api.openPlatform;
  }

  /**
   * 生成微信登录二维码URL
   * @param {string} state - 自定义状态参数
   * @returns {string} 二维码授权URL
   */
  generateQRCodeUrl(state = this.config.state) {
    const params = new URLSearchParams({
      appid: this.config.appId,
      redirect_uri: this.config.redirectUri,
      response_type: 'code',
      scope: this.config.scope,
      state: state
    });
    
    return `${this.api.qrConnect}?${params.toString()}#wechat_redirect`;
  }

  /**
   * 通过授权码获取access_token
   * @param {string} code - 微信授权码
   * @returns {Promise<Object>} access_token信息
   */
  async getAccessToken(code) {
    try {
      // 开发环境使用模拟数据
      if (process.env.NODE_ENV === 'development' || this.config.appId === 'wx1234567890abcdef') {
        console.log('开发环境：使用模拟微信数据');
        return {
          access_token: 'mock_access_token_' + code.slice(-8),
          expires_in: 7200,
          refresh_token: 'mock_refresh_token_' + code.slice(-8),
          openid: 'mock_openid_' + code.slice(-8),
          scope: 'snsapi_login',
          unionid: 'mock_unionid_' + code.slice(-8)
        };
      }

      const params = {
        appid: this.config.appId,
        secret: this.config.appSecret,
        code: code,
        grant_type: 'authorization_code'
      };

      const response = await axios.get(this.api.accessToken, { params });
      
      if (response.data.errcode) {
        throw new Error(`微信API错误: ${response.data.errcode} - ${response.data.errmsg}`);
      }

      return {
        access_token: response.data.access_token,
        expires_in: response.data.expires_in,
        refresh_token: response.data.refresh_token,
        openid: response.data.openid,
        scope: response.data.scope,
        unionid: response.data.unionid
      };
    } catch (error) {
      console.error('获取微信access_token失败:', error);
      throw error;
    }
  }

  /**
   * 刷新access_token
   * @param {string} refresh_token - 刷新令牌
   * @returns {Promise<Object>} 新的access_token信息
   */
  async refreshAccessToken(refresh_token) {
    try {
      const params = {
        appid: this.config.appId,
        grant_type: 'refresh_token',
        refresh_token: refresh_token
      };

      const response = await axios.get(this.api.refreshToken, { params });
      
      if (response.data.errcode) {
        throw new Error(`微信API错误: ${response.data.errcode} - ${response.data.errmsg}`);
      }

      return {
        access_token: response.data.access_token,
        expires_in: response.data.expires_in,
        refresh_token: response.data.refresh_token,
        openid: response.data.openid,
        scope: response.data.scope
      };
    } catch (error) {
      console.error('刷新微信access_token失败:', error);
      throw error;
    }
  }

  /**
   * 获取微信用户信息
   * @param {string} access_token - 访问令牌
   * @param {string} openid - 用户openid
   * @returns {Promise<Object>} 用户信息
   */
  async getUserInfo(access_token, openid) {
    try {
      // 开发环境使用模拟数据
      if (process.env.NODE_ENV === 'development' || access_token.startsWith('mock_')) {
        console.log('开发环境：使用模拟微信用户信息');
        return {
          openid: openid,
          nickname: '模拟微信用户' + openid.slice(-4),
          sex: 1,
          province: '广东',
          city: '深圳',
          country: '中国',
          headimgurl: 'https://via.placeholder.com/100x100/07C160/FFFFFF?text=WX',
          privilege: [],
          unionid: 'mock_unionid_' + openid.slice(-8)
        };
      }

      const params = {
        access_token: access_token,
        openid: openid,
        lang: 'zh_CN'
      };

      const response = await axios.get(this.api.userInfo, { params });
      
      if (response.data.errcode) {
        throw new Error(`微信API错误: ${response.data.errcode} - ${response.data.errmsg}`);
      }

      return {
        openid: response.data.openid,
        nickname: response.data.nickname,
        sex: response.data.sex,
        province: response.data.province,
        city: response.data.city,
        country: response.data.country,
        headimgurl: response.data.headimgurl,
        privilege: response.data.privilege,
        unionid: response.data.unionid
      };
    } catch (error) {
      console.error('获取微信用户信息失败:', error);
      throw error;
    }
  }

  /**
   * 检查access_token是否有效
   * @param {string} access_token - 访问令牌
   * @param {string} openid - 用户openid
   * @returns {Promise<boolean>} 是否有效
   */
  async checkAccessToken(access_token, openid) {
    try {
      const params = {
        access_token: access_token,
        openid: openid
      };

      const response = await axios.get(this.api.userInfo, { params });
      return !response.data.errcode;
    } catch (error) {
      return false;
    }
  }

  /**
   * 完整的微信登录流程
   * @param {string} code - 微信授权码
   * @returns {Promise<Object>} 用户信息
   */
  async completeLogin(code) {
    try {
      // 1. 获取access_token
      const tokenInfo = await this.getAccessToken(code);
      
      // 2. 获取用户信息
      const userInfo = await this.getUserInfo(tokenInfo.access_token, tokenInfo.openid);
      
      // 3. 合并信息
      return {
        ...userInfo,
        access_token: tokenInfo.access_token,
        refresh_token: tokenInfo.refresh_token,
        expires_in: tokenInfo.expires_in
      };
    } catch (error) {
      console.error('微信登录流程失败:', error);
      throw error;
    }
  }

  /**
   * 获取错误信息
   * @param {string} errcode - 错误码
   * @returns {string} 错误信息
   */
  getErrorMessage(errcode) {
    return wechatConfig.errorCodes[errcode] || `未知错误: ${errcode}`;
  }
}

module.exports = new WechatService(); 